﻿using System;
using System.Collections.Generic;
using System.Text;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Jim.Obsidian.Edm;

namespace Jim.Obsidian.Web.Api.Client
{
    public class ApiSubResult
    {

        private string _name;
        private string[] _fields;
        private ApiResult _apiResult;
        private List<ApiObject> values;
        private JObject joResult;

        public string Name
        {
            get { return this._name; }
        }

        public ApiResult Request
        {
            get { return this._apiResult; }
        }

        public ApiSubResult(ApiResult ar, JObject jo)
        {
            joResult = jo;
            this._apiResult = ar;
            this._name = Convert.ToString(((JValue)jo["n"]).Value);
            string strFiles = Convert.ToString(((JValue)jo["f"]).Value);
            this._fields = strFiles.Split(',');
        }

        public int Count
        {
            get
            {
                List<ApiObject> values = this.GetValues();
                return values.Count;
            }
        }

        public ApiObject First
        {
            get
            {
                List<ApiObject> values = this.GetValues();
                if (values.Count > 0)
                    return values[0];
                else
                    return null;
            }
        }

        public List<ApiObject> GetValues()
        {
            if (this.values == null)
            {
                this.values = new List<ApiObject>();
                JArray ja = (JArray)joResult["v"];
                foreach (JToken jt in ja)
                {
                    ApiObject o = new ApiObject();
                    JArray jaArr = (JArray)jt;
                    int len = Math.Min(this._fields.Length, jaArr.Count);
                    for (int i = 0; i < len; i++)
                    {
                        JValue jv = (JValue)jaArr[i];
                        string fileName = this._fields[i];
                        o.Set(fileName, jv.Value);
                    }
                    this.values.Add(o);
                }
            }
            return this.values;
        }

        public List<T> GetModelList<T>() where T : Model, new()
        {
            List<T> list = new List<T>();

            this.values = new List<ApiObject>();
            JArray ja = (JArray)joResult["v"];
            foreach (JToken jt in ja)
            {
                T m = new T();
                ApiObject o = new ApiObject();
                JArray jaArr = (JArray)jt;
                int len = Math.Min(this._fields.Length, jaArr.Count);
                for (int i = 0; i < len; i++)
                {
                    JValue jv = (JValue)jaArr[i];
                    string fileName = this._fields[i];
                    IModelField field = m.GetFieldByJPropName(fileName);
                    if (field != null)
                        field.Set(jv.Value);
                    o.Set(fileName, jv.Value);
                }
                this.values.Add(o);
                list.Add(m);
            }
            return list;
        }

        public T GetFirstModel<T>() where T : Model, new()
        {
            List<T> list = this.GetModelList<T>();
            if (list.Count > 0)
                return list[0];
            else
                return null;
        }

    }
}
